/* UART Events Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
#include "bsp_uart.h"
static const char *TAG = "uart_events";

/**
 * This example shows how to use the UART driver to handle special UART events.
 *
 * It also reads data from UART0 directly, and echoes it to console.
 *
 * - Port: UART2
 * - Receive (Rx) buffer: GPIO5
 * - Transmit (Tx) buffer: GPIO4
 * - Flow control: off
 * - Event queue: on
 * - Pin assignment: TxD (default), RxD (default)
 */

extern void ble_write_char_a(uint8_t *value, uint16_t value_len);//左鞋
extern void ble_write_char_b(uint8_t *value, uint16_t value_len);//右鞋

void usr_uart1_write_bytes(uint8_t *src, uint16_t size)
{
	uart_write_bytes(EX_UART1_NUM, src, size);
}

void usr_uart2_write_bytes(uint8_t *src, uint16_t size)
{
	uart_write_bytes(EX_UART2_NUM, src, size);
}

void bsp_uart1_init(void)
{
	esp_log_level_set(TAG, ESP_LOG_INFO);
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    //Install UART driver, and get the queue.
    uart_driver_install(EX_UART1_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_param_config(EX_UART1_NUM, &uart_config);

    //Set UART pins (using UART0 default pins ie no changes.)
    uart_set_pin(EX_UART1_NUM, 22, 23, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

void bsp_uart2_init(void)
{
    /* Configure parameters of an UART driver,
     * communication pins and install the driver */
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
        .source_clk = UART_SCLK_DEFAULT,
    };
    //Install UART driver, and get the queue.
    uart_driver_install(EX_UART2_NUM, BUF_SIZE * 2, 0, 0, NULL, 0);
    uart_param_config(EX_UART2_NUM, &uart_config);

    //Set UART pins (using UART0 default pins ie no changes.)
    uart_set_pin(EX_UART2_NUM, CONFIG_EXAMPLE_UART_TXD, CONFIG_EXAMPLE_UART_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

static void uart1_task(void *pvParameters)
{
    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

    while (1) {
        // Read data from the UART
        int len = uart_read_bytes(EX_UART1_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
        if (len) {
        	ESP_LOGI(TAG, "[uart1 : %d]", len);
        	ble_write_char_a(data, len);
        }
    }
}

static void uart2_task(void *pvParameters)
{
    // Configure a temporary buffer for the incoming data
    uint8_t *data = (uint8_t *) malloc(BUF_SIZE);

    while (1) {
        // Read data from the UART
        int len = uart_read_bytes(EX_UART2_NUM, data, (BUF_SIZE - 1), 20 / portTICK_PERIOD_MS);
        if (len) {
        	ESP_LOGI(TAG, "[uart2 : %d]", len);
        	ble_write_char_b(data, len);
        }
    }
}

void start_task_uart(void)
{
	xTaskCreate(uart1_task, "uart1_event_task", 2048, NULL, 12, NULL);
	xTaskCreate(uart2_task, "uart2_event_task", 2048, NULL, 12, NULL);
}

static QueueHandle_t sys_queue;
static sys_event_t usr_sys_event_a;
static sys_event_t usr_sys_event_b;

SemaphoreHandle_t MuxSem_Handle;

static void task_sys_message_send(sys_event_t event)
{
    if (NULL != sys_queue)
    {
        xQueueSend(sys_queue, &event, 0);
    }
}

static void task_sys_message_sendFromISR(sys_event_t event)
{
    if (NULL != sys_queue)
    {
    	xQueueSendFromISR(sys_queue, &event, 0);
    }
}

void usr_mqtt_recv_a_msg(uint8_t* buf, uint16_t size)
{
	usr_sys_event_a.type = UART1_SEND_DATA;
	usr_sys_event_a.size = size;
	usr_sys_event_a.buf  = buf;

	xSemaphoreTake(MuxSem_Handle, portMAX_DELAY);
	task_sys_message_send(usr_sys_event_a);
	xSemaphoreGive(MuxSem_Handle);
}

void usr_mqtt_recv_b_msg(uint8_t* buf, uint16_t size)
{
	usr_sys_event_b.type = UART2_SEND_DATA;
	usr_sys_event_b.size = size;
	usr_sys_event_b.buf  = buf;

	xSemaphoreTake(MuxSem_Handle, portMAX_DELAY);
	task_sys_message_send(usr_sys_event_b);
	xSemaphoreGive(MuxSem_Handle);
}

static void sys_mng_task(void *pvParameters)
{
	/* 创建一个互斥量 */
	MuxSem_Handle = xSemaphoreCreateMutex();

	sys_queue = xQueueCreate(40, sizeof(sys_event_t));
	static sys_event_t event = {0};
    while(1){
        if(xQueueReceive(sys_queue, (void *)&event, (TickType_t)(portMAX_DELAY)))
        {
        	switch(event.type)
        	{
        		case UART1_SEND_DATA:
        		{
        			usr_uart1_write_bytes(event.buf, event.size);
        			ESP_LOGI(TAG, "[a DATA]: %d", event.size);
        		}break;
        		case UART2_SEND_DATA:
        		{
        			usr_uart2_write_bytes(event.buf, event.size);
        			ESP_LOGI(TAG, "[b DATA]: %d", event.size);
        		}break;
        	}
        }
    }
}

void start_task_sys(void)
{
	xTaskCreate(sys_mng_task, "sys_mng_task", 4096, NULL, 12, NULL);
}
